/*
 * stdio.h
 * This file has no copyright assigned and is placed in the Public Domain.
 * This file is a part of the clang api package.
 * No warranty is given; refer to the file DISCLAIMER within the package.
 *
 * Definitions of types and prototypes of functions for standard input and
 * output.
 *
 * NOTE: The file manipulation functions provided by Microsoft seem to
 * work with either slash (/) or backslash (\) as the directory separator.
 *
 */

#ifndef _CLANG_PORT_STDIO_H_
#define	_CLANG_PORT_STDIO_H_

/* All the headers include this file. */
#ifndef __IMPL_CLANG_PORT_API_
#	include <_clang_port.h>
#else
#	include <include/_clang_port.h>
#endif

#include <stddef.h>
#include <stdarg.h>

#ifndef __IMPL_CLANG_PORT_API_

/* Flags for the iobuf structure  */
#define	_IOREAD	1 /* currently reading */
#define	_IOWRT	2 /* currently writing */
#define	_IORW	0x0080 /* opened as "r+w" */


/*
 * The three standard file pointers provided by the run time library.
 * NOTE: These will go to the bit-bucket silently in GUI applications!
 */
#define	STDIN_FILENO	0
#define	STDOUT_FILENO	1
#define	STDERR_FILENO	2

/* Returned by various functions on end of file condition or error. */
#define	EOF	(-1)

/*
 * The maximum length of a file name. You should use GetVolumeInformation
 * instead of this constant. But hey, this works.
 * Also defined in io.h.
 */
#define	FILENAME_MAX	(260)

/*
 * The maximum number of files that may be open at once. I have set this to
 * a conservative number. The actual value may be higher.
 */
#define FOPEN_MAX	(20)

/* After creating this many names, tmpnam and tmpfile return NULL */
#define TMP_MAX	32767
/*
 * Tmpnam, tmpfile and, sometimes, _tempnam try to create
 * temp files in the root directory of the current drive
 * (not in pwd, as suggested by some older MS doc's).
 * Redefining these macros does not effect the CRT functions.
 */
#define _P_tmpdir   "\\"
#define _wP_tmpdir  L"\\"

/*
 * The maximum size of name (including NUL) that will be put in the user
 * supplied buffer caName for tmpnam.
 * Inferred from the size of the static buffer returned by tmpnam
 * when passed a NULL argument. May actually be smaller.
 */
#define L_tmpnam (16)

#define _IOFBF    0x0000  /* full buffered */
#define _IOLBF    0x0040  /* line buffered */
#define _IONBF    0x0004  /* not buffered */

#define _IOMYBUF  0x0008  /* stdio malloc()'d buffer */
#define _IOEOF    0x0010  /* EOF reached on read */
#define _IOERR    0x0020  /* I/O error from system */
#define _IOSTRG   0x0040  /* Strange or no file descriptor */
/*
 * The buffer size as used by setbuf such that it is equivalent to
 * (void) setvbuf(fileSetBuffer, caBuffer, _IOFBF, BUFSIZ).
 */
#define	BUFSIZ	512

/* Constants for nOrigin indicating the position relative to which fseek
 * sets the file position.  Defined unconditionally since ISO and POSIX
 * say they are defined here.  */
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2


/*
 * The structure underlying the FILE type.
 *
 * Some believe that nobody in their right mind should make use of the
 * internals of this structure. Provided by Pedro A. Aranda Gutiirrez
 * <paag@tid.es>.
 */
typedef struct _iobuf
{
	char*	_ptr;
	int	_cnt;
	char*	_base;
	int	_flag;
	int	_file;
	int	_charbuf;
	int	_bufsiz;
	char*	_tmpfname;
} FILE;


extern FILE (*_imp___iob)[];	/* A pointer to an array of FILE */

#define _iob	(*_imp___iob)	/* An array of FILE */


#define stdin	(&_iob[STDIN_FILENO])
#define stdout	(&_iob[STDOUT_FILENO])
#define stderr	(&_iob[STDERR_FILENO])


typedef long	fpos_t;

#endif // __IMPL_CLANG_PORT_API_

#ifdef __cplusplus
extern "C" {
#endif
/*
 * File Operations
 */
#ifndef __IMPL_CLANG_PORT_API_

FILE* fopen (const char*, const char*);
FILE* freopen (const char*, const char*, FILE*);
int fflush (FILE*);
int fclose (FILE*);
int remove (const char*);
int rename (const char*, const char*);
FILE* tmpfile (void);
char* tmpnam (char*);
int setvbuf (FILE*, char*, int, size_t);
void setbuf (FILE*, char*);
/*
 * Formatted Output
 */
int fprintf(FILE*, const char*, ...);
int printf(const char*, ...);
int sprintf(char*, const char*, ...);
int snprintf(char*, size_t, const char*, ...);
int vfprintf(FILE*, const char*, va_list);
int vprintf(const char*, va_list);
int vsprintf(char*, const char*, va_list);
int vsnprintf(char*, size_t, const char*, va_list);
/*
 * Formatted Input
 */
int fscanf (FILE*, const char*, ...);
int scanf (const char*, ...);
int sscanf (const char*, const char*, ...);
/*
 * Character Input and Output Functions
 */
int fgetc (FILE*);
char* fgets (char*, int, FILE*);
int fputc (int, FILE*);
int fputs (const char*, FILE*);
char* gets (char*);
int puts (const char*);
int ungetc (int, FILE*);
/* Traditionally, getc and putc are defined as macros. but the
   standard doesn't say that they must be macros.
   We use inline functions here to allow the fast versions
   to be used in C++ with namespace qualification, eg., ::getc.
*/
int getc (FILE*);
int putc (int, FILE*);
int getchar (void);
int putchar (int);
/*
 * Direct Input and Output Functions
 */
size_t fread (void*, size_t, size_t, FILE*);
size_t fwrite (const void*, size_t, size_t, FILE*);
/*
 * File Positioning Functions
 */
int fseek (FILE*, long, int);
long ftell (FILE*);
void rewind (FILE*);


int fgetpos	(FILE*, fpos_t*);
int fsetpos (FILE*, const fpos_t*);
int feof (FILE*);
int ferror (FILE*);

inline int __cdecl feof (FILE* __F)
  { return __F->_flag & _IOEOF; }
inline int __cdecl ferror (FILE* __F)
  { return __F->_flag & _IOERR; }

void clearerr (FILE*);
void perror (const char*);

#endif // __IMPL_CLANG_PORT_API_

#ifdef __cplusplus
}
#endif


#endif /* _CLANG_PORT_STDIO_H_ */
